/**
 * EduVerse Credentials - 系统主入口
 * 
 * 本文件实现了系统的启动逻辑，包括加载配置、创建各个应用实例、设置公共中间件等。
 */

const express = require('express');
const path = require('path');
const dotenv = require('dotenv');
const WalletApp = require('./src/wallet');
const IssuerApp = require('./src/issuer');
const VerifierApp = require('./src/verifier');
const createApiRouter = require('./src/api');

// 加载环境变量
dotenv.config();

// 创建主应用
const app = express();
const port = process.env.PORT || 3000;

// 添加CORS中间件
app.use((req, res, next) => {
  // 设置允许访问的域名，实际生产环境中应该更具体
  res.header('Access-Control-Allow-Origin', '*');
  res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, PATCH, OPTIONS');
  res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization');
  res.header('Access-Control-Max-Age', '3600'); // 预检结果缓存1小时
  
  // 处理OPTIONS预检请求
  if (req.method === 'OPTIONS') {
    console.log(`[${new Date().toISOString()}] 处理OPTIONS预检请求: ${req.url}`);
    return res.status(200).end();
  }
  
  // 添加每个请求的调试日志
  console.log(`[${new Date().toISOString()}] 收到请求: ${req.method} ${req.url} (${req.ip})`);
  
  next();
});

// 公共中间件
app.use(express.json());
app.use(express.static(path.join(__dirname, '../client/build')));

// Schema和上下文文件服务
app.use('/schemas', express.static(path.join(__dirname, 'src/schemas')));

// 创建调试中间件
app.use((req, res, next) => {
  // 记录请求开始时间
  const startTime = Date.now();
  
  // 日志记录
  console.log(`[${new Date().toISOString()}] ${req.method} ${req.url} (${req.ip})`);
  
  // 包装原始的res.json方法，用于调试响应
  const originalJson = res.json;
  res.json = function(body) {
    // 计算响应时间
    const responseTime = Date.now() - startTime;
    console.log(`[${new Date().toISOString()}] 响应: ${JSON.stringify(body).substring(0, 200)}... (${responseTime}ms)`);
    return originalJson.call(this, body);
  };
  
  // 包装原始的res.send方法，用于调试响应
  const originalSend = res.send;
  res.send = function(body) {
    // 计算响应时间
    const responseTime = Date.now() - startTime;
    console.log(`[${new Date().toISOString()}] 发送响应: ${typeof body === 'string' ? body.substring(0, 100) : typeof body}... (${responseTime}ms)`);
    return originalSend.call(this, body);
  };
  
  // 处理错误
  const originalEnd = res.end;
  res.end = function() {
    // 计算响应时间
    const responseTime = Date.now() - startTime;
    if (res.statusCode >= 400) {
      console.error(`[${new Date().toISOString()}] 错误响应: ${res.statusCode} ${res.statusMessage || ''} (${responseTime}ms)`);
    }
    return originalEnd.apply(this, arguments);
  };
  
  // 设置超时处理
  req.setTimeout(60000, () => {
    console.error(`[${new Date().toISOString()}] 请求超时: ${req.method} ${req.url}`);
  });
  
  next();
});

// 启动函数
async function start() {
  try {
    console.log('启动 EduVerse Credentials 系统...');
    
    // SDK配置
    const sdkConfig = {
      circuitsPath: process.env.CIRCUITS_PATH || './circuits',
      rpcUrl: process.env.POLYGON_AMOY_RPC_URL,
      rhsUrl: process.env.RHS_URL,
      dataStoragePath: process.env.DATA_STORAGE_PATH || './data'
    };
    
    // 创建并初始化各个应用组件
    // 根据实际需求，可能只使用其中一个或多个组件
    
    // 钱包应用
    const walletApp = new WalletApp();
    await walletApp.initialize(sdkConfig);
    app.use('/wallet', walletApp.app);
    console.log('钱包应用已初始化');
    
    // 发行方门户
    const issuerApp = new IssuerApp();
    await issuerApp.initialize({
      ...sdkConfig,
      statusListBaseUrl: process.env.STATUS_LIST_BASE_URL
    });
    app.use('/issuer', issuerApp.app);
    console.log('发行方门户已初始化');
    
    // 验证方接口
    const verifierApp = new VerifierApp();
    await verifierApp.initialize(sdkConfig);
    app.use('/verifier', verifierApp.app);
    console.log('验证方接口已初始化');
    
    // 创建API路由器并挂载到/api路径
    const apiRouter = createApiRouter({
      walletApp,
      issuerApp,
      verifierApp
    });
    app.use('/api', apiRouter);
    console.log('API路由已挂载到/api路径');
    
    // API健康检查端点
    app.get('/api/health', (req, res) => {
      res.json({ status: 'ok', time: new Date().toISOString() });
    });
    
    // 最后才注册SPA路由处理，确保API路由优先匹配
    // 处理SPA路由 - 所有不匹配其它路由的请求都返回index.html
    app.get('*', (req, res, next) => {
      // 如果请求的是API或特定资源，则继续处理
      if (req.url.startsWith('/api') || 
          req.url.startsWith('/wallet/api') || 
          req.url.startsWith('/issuer/api') || 
          req.url.startsWith('/verifier/api') ||
          req.url.includes('.')) {
        return next();
      }
      
      // 所有其他前端路由请求返回前端应用的index.html
      res.sendFile(path.join(__dirname, '../client/build/index.html'));
    });
    
    // 整合钱包API路由
    if (walletApp && walletApp.router) {
      apiRouter.use('/wallet', walletApp.router);
    }

    // 整合发行方API路由
    if (issuerApp && issuerApp.router) {
      apiRouter.use('/issuer', issuerApp.router);
    }

    // 整合验证方API路由
    if (verifierApp && verifierApp.router) {
      apiRouter.use('/verifier', verifierApp.router);
    }
    
    // 启动服务器
    app.listen(port, () => {
      console.log(`EduVerse Credentials 系统已启动，监听端口: ${port}`);
    });
  } catch (error) {
    console.error('系统启动失败:', error);
    process.exit(1);
  }
}

// 启动系统
if (require.main === module) {
  start();
}

module.exports = { app, start }; 